package cn.edu.cug.cs.gtl.plugins.device.actions;

import cn.edu.cug.cs.gtl.apis.ui.AbstractApplication;
import cn.edu.cug.cs.gtl.apis.ui.actions.AbstractAction;
import cn.edu.cug.cs.gtl.apis.ui.datake.devicetree.DeviceTree;
import cn.edu.cug.cs.gtl.apis.ui.tree.TreeNodeData;
import cn.edu.cug.cs.gtl.plugins.device.common.DBUtils;
import cn.edu.cug.cs.gtl.plugins.device.dialog.StorageClusterDialog;
import cn.edu.cug.cs.gtl.protos.StorageCluster;
import cn.edu.cug.cs.gtl.utils.impl.DataDeviceManagerImpl;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.event.ActionEvent;
import java.util.Locale;
import java.util.ResourceBundle;

public class UpdateStorageClusterAction extends AbstractAction {
    private DBUtils dbUtils = new DBUtils();

    @Override
    public void initialize(AbstractApplication theApp) {
        ResourceBundle resourceBundle = ResourceBundle.getBundle("device-resource", Locale.getDefault());
        name = resourceBundle.getString("popupmenu.device.tree.update_storage_cluster");
        menuItem.setText(name);

        this.theApp = theApp;
        menuItem.addActionListener(this);
        ((DeviceTree) theApp.getMainFrame().asDatakeFrame().getDevicePanel().getTreeComponent()).getStorageClusterNodePopupMenu().add(menuItem);
        ((DeviceTree) theApp.getMainFrame().asDatakeFrame().getDevicePanel().getTreeComponent()).getStorageChildNodePopupMenu().add(menuItem);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //获取当前选中的集群节点
        TreeNodeData deviceTreeNodeData = (TreeNodeData) theApp.getMainFrame().asDatakeFrame().getDevicePanel().getTreeComponent().getCurrentSelectedNode().getUserObject();
        Object refObject = deviceTreeNodeData.getRefObject();

        // 弹出窗口，修改集群配置信息
        StorageClusterDialog clusterDialog = new StorageClusterDialog((JFrame) SwingUtilities.getWindowAncestor(menuItem));
        if (refObject instanceof StorageCluster) {
            StorageCluster storageCluster = (StorageCluster) refObject;
            //设置弹出窗口的初始值
            clusterDialog.setInitialValues(storageCluster.getAlias(), storageCluster.getUrl(), storageCluster.getUserName(), storageCluster.getPassword());
        }
        clusterDialog.setVisible(true);


        // 获取输入的集群配置信息
        String connectionName = clusterDialog.getConnectionName();
        String url = clusterDialog.getUrl();
        String user = clusterDialog.getUser();
        String password = clusterDialog.getPassword();

        // Perform the connection test (you need to implement this method)
        boolean isConnected = false;

        if (clusterDialog.isConfirmed()) {
            //获取当前选中的节点的父节点数据，进而判断使用哪个对应的方法
            DefaultMutableTreeNode currentSelectedNode = theApp.getMainFrame().asDatakeFrame().getDevicePanel().getTreeComponent().getCurrentSelectedNode();
            DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) currentSelectedNode.getParent();

            Object obj = ((TreeNodeData) parentNode.getUserObject()).getRefObject();
            if (obj.equals("Hadoop HDFS")) {
                isConnected = dbUtils.connectionForHDFS(url, user, password);
            } else if (obj.equals("MinIO")) {
                isConnected = dbUtils.connectionForMinIo(url, user, password);
            } else if (obj.equals("PostgreSQL")) {
                isConnected = dbUtils.connectionForPostgreSQL(url, user, password);
            } else if (obj.equals("MySQL")) {
                isConnected = dbUtils.connectionForMySQL(url, user, password);
            } else if (obj.equals("Oracle")) {
                isConnected = dbUtils.connectionForOracle(url, user, password);
            } else if (obj.equals("MongoDB")) {
                isConnected = dbUtils.connectionForMongoDB(url, user, password);
            }

            // 显示结果信息
            if (isConnected) {
                String message = "修改存储集群成功！";
                String title = "连接成功";
                JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE);

                // 从选中节点中获取原始节点对象
                TreeNodeData treeNodeData = (TreeNodeData) currentSelectedNode.getUserObject();
                StorageCluster oldStorageCluster = (StorageCluster)treeNodeData.getRefObject();


                //连接成功，则将配置信息保存
                //注意：修改的connectionName只是数据库中的alias，而不是name;name不能被修改，并且需要通过name来查找数据库中的记录
                StorageCluster storageCluster = StorageCluster.newBuilder()
                        .setName(oldStorageCluster.getName())
                        .setAlias(connectionName)
                        .setType(obj.toString())
                        .setUrl(url)
                        .setUserName(user)
                        .setPassword(password)
                        .build();

                updateStorageClusterNode(storageCluster);
            } else {
                String message = "修改存储集群失败，请检查配置信息是否正确！";
                String title = "连接失败";
                JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
            }

        }

    }

    //将输入的配置信息保存为节点对象，并且存入数据库中
    public void updateStorageClusterNode(StorageCluster storageCluster) {
        DeviceTree tree = (DeviceTree) theApp.getMainFrame().asDatakeFrame().getDevicePanel().getTreeComponent();
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();

        //更新数据库中数据
        DataDeviceManagerImpl dataDeviceManager = new DataDeviceManagerImpl();
        int id = dataDeviceManager.getIdByName(storageCluster.getName());
        dataDeviceManager.updateStorageCluster(storageCluster, id);

        // 从选中节点中获取原始节点对象
        TreeNodeData treeNodeData = (TreeNodeData) selectedNode.getUserObject();

        //更新节点信息
        treeNodeData.setText(storageCluster.getAlias());
        treeNodeData.setRefObject(storageCluster);
        selectedNode.setUserObject(treeNodeData);

        //更新节点，通知树视图进行更新
        DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
        treeModel.nodeChanged(selectedNode);
        treeModel.reload(selectedNode);

        //将新节点变为可视
        TreeNode[] nodes = treeModel.getPathToRoot(selectedNode);
        tree.scrollPathToVisible(new TreePath(nodes));    //构造一个从根节点到新添加节点的树路径，由于我们的树放在一个滚动面板中，这样会告诉外围的滚动面板将路径末端的节点滚动到视图中在·
//        tree.expandPath(tree.getSelectionPath());

    }
}
